<?php

namespace app\api\controller;

use app\admin\model\BillModel;
use app\admin\model\BuildingModel;
use app\admin\model\BuildingRoomBoardModel;
use app\admin\model\BuildingRoomFixedModel;
use app\admin\model\BuildingRoomModel;
use app\admin\model\BuildingRoomPtModel;
use app\admin\model\ContractFixedModel;
use app\admin\model\ContractPtModel;
use app\admin\model\RoomBoardLogModel;
use app\admin\model\SmsRechargeLogModel;
use app\admin\model\SmsSendLogModel;
use app\admin\model\VacantModel;
use app\common\controller\Api;
use app\common\model\PaymentRecords;
use think\Db;
use think\Exception;
use think\exception\PDOException;


class Bill extends Api
{
    protected $noNeedLogin = [];
    protected $noNeedRight = ['*'];

    /**
     * @var BillModel
     */
    protected $model = null;

    protected $user_id = 0;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new BillModel();
        $this->user_id = $this->auth->id;
    }

    public function index()
    {
        $page_size = $this->request->param('page_size/d', 15);
        $kw = $this->request->param('kw/s', '');
        $room_id = $this->request->param('room_id/d', 0);
        $sort = $this->request->param('sort/s', 'b.id');
        $way = $this->request->param('way/s', 'desc');
        $status = $this->request->param('status', '');
        $build_id = $this->request->param('build_id/d', '');
        $date_type = $this->request->param('date_type');
        $start = $this->request->param('start');
        $end = $this->request->param('end');
        $where = [];
        if ($room_id) {
            $kw = '';
            $where['c.build_id'] = $room_id;
        }
        if ($kw) {
            $where['room_name|user_name|user_phone'] = ['like', '%' . $kw . '%'];
        }
        if (isset($status) && $status != '') {
            $where['b.status'] = $status;
        }

        $build_ids = BuildingModel::getUserBuildingIds($this->auth->id);
        if ($build_id) {
            $build_ids = array_intersect($build_ids, [$build_id]);
        }
        $where['build_id'] = ['in', $build_ids];
        $where['b.type'] = ['in', [1, 3, 4, 5, 6]];

        if ($date_type) {
            if ($date_type == 1) {
                $where['b.day'] = ['between time', setTimes('today')];
            } elseif ($date_type == 2) {
                $where['b.day'] = ['between time', setTimes('thisweek')];
            } elseif ($date_type == 3) {
                $where['b.day'] = ['between time', setTimes('thismonth')];
            } elseif ($date_type == 4) {
                $where['b.day'] = ['between time', setTimes('thisyear')];
            }
        }

        if ($start && $end) {
            $where['b.day'] = ['between time', [$start, $end]];
        } elseif ($start) {
            $where['b.day'] = ['>= time', $start];
        } elseif ($end) {
            $where['b.day'] = ['<= time', $end];
        }



        $list = $this->model->alias('b')
            ->join('user_contract c', 'c.id = b.contract_id', 'left')
            ->where($where)
            ->order($sort, $way)
            ->order('b.id', 'desc')
            ->field('b.id,b.status,b.money,b.pay_time,b.day,b.remark,c.user_name,c.user_phone,c.room_name,c.build_address,c.build_name')
            ->paginate($page_size)->each(function ($item) {
                $item->overdue_day = 0;
                if ($item->status == 1 && date('Y-m-d') > $item->day) {
                    $date1 = new \DateTime(date('Y-m-d'));
                    $date2 = new \DateTime($item->day);
                    $item->overdue_day = $date1->diff($date2)->days;
                }
            });
            file_put_contents('bill.txt',$this->model->getLastSql());
        $list = $list->toArray();

        // 合计金额
        $list['total_sum_money'] = $this->model->alias('b')
            ->join('user_contract c', 'c.id = b.contract_id', 'left')
            ->where($where)
            ->sum('money');

        // 总待收金额
        $where['b.status'] = 1;
        $list['total_ds_money'] = $this->model->alias('b')
            ->join('user_contract c', 'c.id = b.contract_id', 'left')
            ->where($where)
            ->sum('money');



        $this->success('请求成功', $list);
    }

    public function index_stat()
    {
        $kw = $this->request->param('kw/s', '');
        $build_id = $this->request->param('build_id/d', '');
        $date_type = $this->request->param('date_type');
        $start = $this->request->param('start');
        $end = $this->request->param('end');
        $where = [];
        if ($kw) {
            $where['room_name|user_name|user_phone'] = ['like', '%' . $kw . '%'];
        }

        $build_ids = BuildingModel::getUserBuildingIds($this->auth->id);
        if ($build_id) {
            $build_ids = array_intersect($build_ids, [$build_id]);
        }
        $where['build_id'] = ['in', $build_ids];
        $where['b.type'] = ['in', [1, 3, 4, 5, 6]];

        if ($date_type) {
            if ($date_type == 1) {
                $where['b.day'] = ['between time', setTimes('today')];
            } elseif ($date_type == 2) {
                $where['b.day'] = ['between time', setTimes('thisweek')];
            } elseif ($date_type == 3) {
                $where['b.day'] = ['between time', setTimes('thismonth')];
            } elseif ($date_type == 4) {
                $where['b.day'] = ['between time', setTimes('thisyear')];
            }
        }

        if ($start && $end) {
            $where['b.day'] = ['between time', [$start, $end]];
        } elseif ($start) {
            $where['b.day'] = ['>= time', $start];
        } elseif ($end) {
            $where['b.day'] = ['<= time', $end];
        }

        $list = $this->model->alias('b')
            ->join('user_contract c', 'c.id = b.contract_id', 'left')
            ->where($where)
            ->group('b.status')
            ->column('count(*) as num', 'b.status');

        $all = $this->model->alias('b')
            ->join('user_contract c', 'c.id = b.contract_id', 'left')
            ->where($where)->count();
        $data = [
            'all' => $all,
            'dai_shen' => $list[0] ?? 0,
            'dai_shou' => $list[1] ?? 0,
            'yi_shou' => $list[2] ?? 0,
        ];

        $this->success('ok', $data);
    }

    public function history_bill()
    {
        $room_id = $this->request->param('room_id/d', 0);
        $page_size = $this->request->param('page_size/d', 15);
        $kw = $this->request->param('kw/s', '');
        $sort = $this->request->param('sort/s', 'b.id');
        $way = $this->request->param('way/s', 'desc');
        $status = $this->request->param('status', '');
        $where = [];
        if ($kw) {
            $where['room_name|user_name|user_phone'] = ['like', '%' . $kw . '%'];
        }
        if (isset($status) && $status != '') {
            $where['b.status'] = $status;
        }

        $build_ids = BuildingModel::getUserBuildingIds($this->auth->id);
        $where['build_id'] = ['in', $build_ids];
        $where['room_id'] = $room_id;
        $list = $this->model->alias('b')
            ->join('user_contract c', 'c.id = b.contract_id', 'left')
            ->where($where)
            ->order($sort, $way)
            ->field('b.id,b.status,b.money,b.pay_time,b.day,b.remark,c.user_name,c.user_phone')
            ->paginate($page_size);

        $this->success('请求成功', $list);
    }


    public function info()
    {
        $id = $this->request->param('id/', 0);
        if ($id < 1) {
            $this->error('id错误');
        }
        $bill = $this->model::get($id, ['contract' => function ($query) {
            $query->field('id,build_address,build_name,room_id,room_name,user_name,user_phone,money_zu');
        }]);
        if (empty($bill)) {
            $this->error('账单不存在');
        }
        $fixed = ContractFixedModel::where('contract_id', $bill->contract_id)
            ->field('cfg_id,type_name,price')->select();

        $fixed_data = [];

        if ($bill->type == 1 && $bill->is_first) {
            $fixed_data[] = [
                'type_name' => '首次租金',
                'price' => $bill['money'] ?? 0,
            ];
        } elseif(!in_array($bill->type,[3,4,5])) {
            $fixed_data[] = [
                'type_name' => '租金',
                'price' => $bill['contract']['money_zu'] ?? 0,
            ];
            foreach ($fixed as $item) {
                if (in_array($item['cfg_id'], [1, 2, 3])) {
                    continue;
                }
                $fixed_data[] = $item->toArray();
            }
        }




        $bill['fixed'] = $fixed_data;


        /*$bill['pt'] = ContractPtModel::where('contract_id', $bill->contract_id)
            ->field('name,num,deposit,remark')->select();*/

        $bill['water_electricity'] = RoomBoardLogModel::where([
            'room_id' => $bill['contract']['room_id'] ?? 0,
            'type' => ['in', [1,2,3]],
            'month' => $bill['month'],
            'id' => $bill['rid'],
        ])
            ->field('type,name,num,last_num,use_num,price,money')
            ->select();
        if($bill['period'] == null){
            $bill['period'] == '';
        }
        $this->success('ok', $bill);
    }


    public function del()
    {
        $ids = $this->request->param('ids');

        $list = $this->model->where('id', 'in', $ids)->select();

        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                // 已收款不可删除
                if ($item->status == 2) continue;
                $item->data('del_uid', $this->auth->id);
                $count += $item->delete();

                PaymentRecords::destroy(['relation_id' => $item->id]);
            }
            Db::commit();
        } catch (PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error('删除失败');
    }

    public function audit()
    {
        $ids = $this->request->param('ids');

        $list = $this->model->where('id', 'in', $ids)->select();

        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                // 已收款不可再审核
                if ($item->status == 2) continue;
                $count += $item->save(['status' => 1]);
            }
            Db::commit();
        } catch (PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error('失败');
    }

    public function receive_payment()
    {
        $ids = $this->request->param('ids');

        $list = $this->model->where('id', 'in', $ids)->select();

        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                // 不是待审核不处理
                if ($item->status != 1) continue;
                $count += $item->save(['status' => 2, 'pay_time' => date('Y-m-d H:i:s')]);

                PaymentRecords::update(['status' => 1], ['relation_id' => $item->id]);
            }
            Db::commit();
        } catch (PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error('失败');
    }

    public function revoke()
    {
        $ids = $this->request->param('ids');

        $list = $this->model->where('id', 'in', $ids)->select();

        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                // 不是已支付不处理
                if ($item->status != 2) continue;
                $count += $item->save(['status' => 1, 'pay_time' => null]);

                PaymentRecords::update(['status' => 0], ['relation_id' => $item->id]);
            }
            Db::commit();
        } catch (PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error('失败');

    }

    public function sms()
    {
        $id = $this->request->param('id/d');
        $row = $this->model::get($id);
        if (empty($row)) {
            $this->error('数据不存在');
        }
        $contract = \app\admin\model\user\Contract::get($row->contract_id);
        if (empty($contract)) {
            $this->error('关联合同不存在');
        }
        $rechargeLog = SmsRechargeLogModel::isCanSend($this->user_id);
        if (!$rechargeLog) {
            $this->error('请先充值短信');
        }

        Db::startTrans();
        try {
            $mobile = $contract->user_phone;
            // 短信模板参数
            $param = [
                'address' => $contract->build_address . $contract->room_name,
                'money' => $row->money,
                'date' => $row->month . '-' . $contract->rent_day,
            ];


            SmsSendLogModel::create([
                'user_id' => $this->user_id,
                'contract_id' => $row->contract_id,
                'bill_id' => $id,
                'mobile' => $mobile,
                'content' => sprintf('尊敬的用户您好，您租住的%s，房租%s元，交租日期%s，为避免给您的生活带来不便，请及时缴纳。',
                    $param['address'], $param['money'], $param['date'])
            ]);

            $rechargeLog->send_num += 1;
            $rechargeLog->save();

            $res = \app\common\library\Sms::notice($mobile, $param, 'SMS_492610192');
            if (!$res) {
                throw new Exception('短信发送失败，请检查短信配置');
            }

            Db::commit();
        } catch (\Throwable $e) {
            Db::rollback();
            trace('发布短信失败：' . $e->getTraceAsString());
            $this->error($e->getMessage());
        }
        $this->success('成功');
    }


    public function year()
    {
        $page_size = $this->request->param('page_size/d', 15);
        $list = $this->model
            ->where('user_id', $this->user_id)
            ->where('type', 1)
            ->whereIn('status', [1, 2])
            ->field('year,sum(money) as total_money')
            ->group('year')
            ->paginate($page_size)->each(function ($item) {
                $pay = $this->model
                    ->where('user_id', $this->user_id)
                    ->where('type', 1)
                    ->where('year', $item->year)
                    ->where('status', 2)
                    ->sum('money');
                $un_pay = $this->model
                    ->where('user_id', $this->user_id)
                    ->where('type', 1)
                    ->where('year', $item->year)
                    ->where('status', 1)
                    ->sum('money');

                $item->pay = $pay;
                $item->un_pay = $un_pay;
            });

        $this->success('', $list);
    }

    public function day()
    {
        $page_size = $this->request->param('page_size/d', 15);
        $list = $this->model
            ->where('user_id', $this->user_id)
            ->where('type', 1)
            ->whereIn('status', [1, 2])
            ->field('day,sum(money) as total_money')
            ->group('day')
            ->paginate($page_size)->each(function ($item) {
                $pay = $this->model
                    ->where('user_id', $this->user_id)
                    ->where('type', 1)
                    ->where('day', $item->day)
                    ->where('status', 2)
                    ->sum('money');
                $un_pay = $this->model
                    ->where('user_id', $this->user_id)
                    ->where('type', 1)
                    ->where('day', $item->day)
                    ->where('status', 1)
                    ->sum('money');

                $item->pay = $pay;
                $item->un_pay = $un_pay;
            });

        $this->success('', $list);
    }


    public function category_stat()
    {
        $page_size = $this->request->param('page_size/d', 15);
        $kw = $this->request->param('kw/s', '');
        $build_id = $this->request->param('build_id/d', '');
        $where = [];
        if ($kw) {
            $where['category'] = ['like', '%' . $kw . '%'];
        }
        $build_ids = BuildingModel::getUserBuildingIds($this->auth->id);
        if ($build_id) {
            $build_ids = array_intersect($build_ids, [$build_id]);
        }
        $where['contract_id'] = ['in', function ($query) use ($build_ids) {
            $query->name('user_contract')->whereIn('build_id', $build_ids)->field('id');
        }];
        $where['status'] = 2;
        $list = $this->model
            ->where($where)
            ->field('month,category,sum(money) as total_money')
            ->group('month,category')
            ->paginate($page_size);

        $this->success('', $list);
    }


    public function deposit_stat()
    {
        $page_size = $this->request->param('page_size/d', 15);
        $kw = $this->request->param('kw/s', '');
        $sort = $this->request->param('sort/s', 'b.id');
        $way = $this->request->param('way/s', 'desc');
        $day = $this->request->param('day/d', '');
        $build_id = $this->request->param('build_id/d', '');
        $where = [];
        if ($kw) {
            $where['room_name|b.remark'] = ['like', '%' . $kw . '%'];
        }
        if ($day) {
            $where['b.expire_date'] = ['between time', [strtotime("-$day days"), time()]];
        }

        $build_ids = BuildingModel::getUserBuildingIds($this->auth->id);
        if ($build_id) {
            $build_ids = array_intersect($build_ids, [$build_id]);
        }
        $where['build_id'] = ['in', $build_ids];
        $where['b.type'] = 2;
        $list = $this->model->alias('b')
            ->join('user_contract c', 'c.id = b.contract_id', 'left')
            ->where($where)
            ->order($sort, $way)
            ->field('b.id,b.contract_id,b.expire_date,b.remark,b.money,c.build_address,c.room_name')
            ->paginate($page_size);

        $list = $list->toArray();

        $list['total_sum_money'] = $this->model->alias('b')
            ->join('user_contract c', 'c.id = b.contract_id', 'left')
            ->where($where)
            ->sum('b.money');

        $this->success('请求成功', $list);
    }


    public function board_stat()
    {
        $page_size = $this->request->param('page_size/d', 15);
        $type = $this->request->param('type/d', 0);
        $build_id = $this->request->param('build_id/d', '');
        $where = [];

        $build_ids = BuildingModel::getUserBuildingIds($this->auth->id);
        if ($build_id) {
            $build_ids = array_intersect($build_ids, [$build_id]);
        }

        $room_ids = BuildingRoomModel::whereIn('build_id', $build_ids)->column('id');
        $where['room_id'] = ['in', $room_ids];

        if ($type) {
            $where['type'] = $type;
        }

        $list = RoomBoardLogModel::where($where)
            ->field('month,sum(use_num) as total_use_num,sum(money) as total_money')
            ->group('month')
            ->order('month','desc')
            ->paginate($page_size);

        $this->success('请求成功', $list);
    }


    public function vacant_stat()
    {
        $page_size = $this->request->param('page_size/d', 15);
        $type = $this->request->param('type/d', 0);
        $where = [];

        $where['user_id'] = $this->user_id;
        if ($type == 1) {
            $where['month'] = date('Y-m');
        } elseif ($type == 2) {
            $where['month'] = date('Y-m', strtotime('last month'));
        } elseif ($type == 3) {
            $where['year'] = date('Y');
        } elseif ($type == 4) {
            $where['year'] = date('Y', strtotime('last year'));
        }

        $list = VacantModel::where($where)
            ->field('day,total_num,rent_num,rate')
            ->order('id', 'desc')
            ->paginate($page_size);

        $this->success('请求成功', $list);
    }

}
